/* ==================================================================
* Copyright (c) 2024/11/15 SCNU LiuJunJie z-ken
* All rights reserved.
* fileName:	myalgor.h
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the xxx Group. and
* its contributors.
* 4. Neither the name of the Group nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Author,GROUP AND CONTRIBUTORS
* ===================================================================
* Author: LiuJunJie z-ken.
*/

#if !defined(MY_ALGOR_H)
#define MY_ALGOR_H

#include <iostream>

using namespace std;

#include <string>

#include "lalr.h"
#include "production.h"

class ParseAlgor {
private:
    unordered_map<string, string> productionsNameMapping = {{"minic", "./minic_config.txt"},
                                                            {"tiny",  "./tiny_config.txt"},
                                                            {"exp",   "./exp_config.txt"}};;

    /**
     * 初始化attributeConfigFile的路径，如果有直接指定内置文法名称（如：minic），那么就无需手动使用映射中的路径
     */
    void initAttributeFilePath() {
        // 如果不是使用配置文件，就一定要更新文法名称
        if (!onlyUseConfigAst) {
            this->attributeConfigFile = productionsNameMapping[productionsName];
        }
    }

    void debug_analyse();

    /**
     * LR核心算法执行。
     * 此算法是基于coreGenerateProductions产生的结果进行使用的，需要注意调用顺序
     */
    void coreGenerateLR();

    void coreGenerateProductions(const string &productionFileName);

    // 是否仅仅使用配置文件方式生成语法树
    bool onlyUseConfigAst = true;
    // 配置文件的路径
    string attributeConfigFile;
public:
    /**
     * 配置文件的路径
     * @return
     */
    const string &getAttributeConfigFile() const;

    /**
     * 配置文件的路径
     * @param attributeConfigFile
     */
    void setAttributeConfigFile(const string &attributeConfigFile);

public:
    /**
     * 只使用配置文件语法树
     * @return
     */
    bool isOnlyUseConfigAst() const;

    /**
     * 只使用配置文件的语法树
     * @param useConfigAst
     */
    void setOnlyUseConfigAst(bool useConfigAst);


public:
    string productionsName;

/**
     *
     * @param productionFileName :设置的文法内容文件路径
     * @param matchFilePath :需要进行分析表分析的文件
     * @param matchFileContentPath :通过DFA分析正则分析器,输出的匹配到的字符串的内容的文件
     */
    void process(string productionFileName, string matchFilePath = "../match.txt",
                 string matchFileContentPath = "../outputContent.txt");

    /**
     *
     * @param productionFilePath 文法路径
     * @param programeFilePath 符合文法编写的程序路径
     * @param jointFilePath tokenType分析器程序路径
     */
    void processWithTokenParser(const string &productionFilePath, const string &programeFilePath,
                                const string &jointFilePath = "../joint.cpp");

    /**
     *
     * @param productionFileName :设置的文法内容文件路径
     * @param matchFilePath :需要进行分析表分析的文件
     * @param matchFileContentPath :通过DFA分析正则分析器,输出的匹配到的字符串的内容的文件
     */
    void processSingleMode(string productionFileName, string matchFilePath = "../match.txt"); // 支持单文件编码的模式

    /**
     * 单编码文件模式
     * @param productionFilePath
     * @param programeFilePath
     * @param jointFilePath
     */
    void processWithTokenParserSingleMode(const string &productionFilePath, const string &programeFilePath,
                                          const string &jointFilePath = "../joint.cpp");


    /**
     * 只生成不分析
     * 单独生成DFA和分析表，然后停止，宏观上可以认为是processSingleMode在开始分析串之前的所有代码
     * @param productionFilePath
     */
    void processGenerateDfaAndAnalyseSheet(const string &productionFilePath);

    /**
     * 单独分析
     * 使用源程序进行分析
     * 单独进行对源程序的分析，需要指定分析代码位置和分析器代码位置
     * @param programeFilePath
     * @param jointFilePath
     */
    void processAnalyseProgramByAnalyser(const string &programeFilePath, const string &jointFilePath = "../joint.cpp");

    /**
     * 单独分析
     * 使用编码文件进行分析
     * @param matchFilePath
     */
    void processAnalyseProgramByEncodingFile(const string &encodingFilePath);

    // ProductionUtil ProductionUtil1;
    LALR lalrUtil1;

    void clean();
};

#endif // MY_ALGOR_H
